/*
MIT License

Copyright (c) 2022 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,

https://bmstu.codes/lsx/simodo/loom
*/

#ifndef simodo_interpret_host_fuze_HostAnalyzer
#define simodo_interpret_host_fuze_HostAnalyzer

/*! \file FuzeAnalyzer.h
    \brief Анализ операторов Fuze с использованием внутренней машиной SIMODO
*/

#include "simodo/interpret/builtins/hosts/fuze/FuzeInterpret_abstract.h"
#include "simodo/interpret/SemanticDataCollector_interface.h"
#include "simodo/inout/reporter/Reporter_abstract.h"

#include <map>

namespace simodo::interpret::builtins
{
    inline const size_t FUZE_MAX_NUMBER_OF_MISTAKES = 5;

    class FuzeAnalyzer: public FuzeInterpret_abstract
    {
        SemanticDataCollector_interface &   _collector;
        size_t                              _number_of_mistakes = 0;

        std::multimap<std::u16string,std::pair<inout::Token, std::vector<inout::Token>>> 
                                            _productions;
        std::vector<inout::Token>           _directions;

    public:
        FuzeAnalyzer(Interpret * inter, 
                 std::string grammar_name,
                 parser::Grammar & grammar,
                 parser::TableBuildMethod method=parser::TableBuildMethod::none,
                 bool need_strict_rule_consistency=true);

        FuzeAnalyzer(Interpret * inter, 
                 SemanticDataCollector_interface & collector,
                 std::string grammar_name,
                 parser::Grammar & grammar,
                 parser::TableBuildMethod method=parser::TableBuildMethod::none,
                 bool need_strict_rule_consistency=true);

    public:
        // getters and swaps:
        const std::multimap<std::u16string,std::pair<inout::Token, std::vector<inout::Token>>> &
                        productions() const { return _productions; }
        const std::vector<inout::Token> & directions() const { return _directions; }

        void            swapProductions(std::multimap<std::u16string,std::pair<inout::Token, std::vector<inout::Token>>> & prods)
        {
            _productions.swap(prods);
        }
        void            swapDirections(std::vector<inout::Token> & dirs)
        {
            _directions.swap(dirs);
        }

    // Наследие SemanticModule_interface
    public:
        virtual bool checkInterpretType(InterpretType interpret_type) const override { return interpret_type == InterpretType::Analyzer; }

    // Группа методов непосредственно отвечающих за выполнение уже разобранной и подготовленной операции.

    public:
        virtual InterpretState   executeGlobalScript (const inout::Token & label, const simodo::ast::Node & script) override;
        virtual InterpretState   executeProduction   (const inout::Token & production, 
                                             const std::vector<inout::Token> & pattern, 
                                             const inout::Token & direction_token,
                                             const simodo::ast::Node & action) override;
        virtual InterpretState   executeRef          (const inout::Token & token, const std::u16string & ref) override;
    };
}

#endif // simodo_interpret_host_fuze_HostAnalyzer
